<?php
// WebSVN - Subversion repository viewing via the web using PHP
// Copyright (C) 2004-2006 Tim Armes
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA	02111-1307	USA
//
// --
//
// db.php
//
// Handle reading and interpretation of an SVN auth file
require_once 'include/class.accessfile.php';

function pathFilter($path) {
    return ($path == '/')?$path:rtrim($path, '/');
}
function rebuildAccessFile($config) {
    $accessfile = new AccessFile($config);
    $accessfile->createFromDatabase();
}

function addOrUpdatePrivileges($name, $repositoryName, $path, $access, $option, $config) {

    $db         = $config->db;
    $o_table    = $option . 's';
    $o_pritable = $option . 'privileges';
    $o_id       = $option . 'id';

    $s_name     = makeSqlString($name);
    $results    = $db->Execute("SELECT id FROM $o_table WHERE name = $s_name");
    $s_id       = $results->fields['id'];

    $s_repositoryName   = makeSqlString($repositoryName);
    $results            = $db->Execute("SELECT id FROM repositories WHERE name = $s_repositoryName");
    $s_repositoryid     = $results->fields['id'];

    $s_path = makeSqlString(pathFilter($path));
    $s_access = makeSqlString($access);


    $results = $db->Execute("SELECT * FROM $o_pritable WHERE $o_id = $s_id AND repositoryid = $s_repositoryid AND path = $s_path");
    
    if ($results->fields) {
        $db->Execute("UPDATE $o_pritable SET access = $s_access 
            WHERE $o_id = $s_id AND repositoryid = $s_repositoryid AND path = $s_path");
    } else {
        $db->Execute("INSERT INTO $o_pritable (id, $o_id, repositoryid, path, access) VALUES (null, 
            $s_id, $s_repositoryid, $s_path, $s_access)");
    }
}

function modifyOrRemovePrivileges($name, $repositoryName, $path, $level, $type, $option, $config, $dispath = null) {

    $db         = $config->db;
    $o_table    = $option . 's';
    $o_pritable = $option . 'privileges';
    $o_id       = $option . 'id';

    $s_name     = makeSqlString($name);
    $results    = $db->Execute("SELECT id FROM $o_table WHERE name = $s_name");
    $s_id       = $results->fields['id'];

    $s_repositoryName   = makeSqlString($repositoryName);
    $results            = $db->Execute("SELECT id FROM repositories WHERE name = $s_repositoryName");
    $s_repositoryid     = $results->fields['id'];

    $s_path = pathFilter($path);

    if ($level == 0 ) {
        $results = $db->Execute("SELECT * FROM $o_pritable WHERE $o_id = $s_id AND repositoryid = $s_repositoryid");
        if (!$results) 
            print $db->ErrorMsg();
        else
            while (!$results->EOF) {
                $tmpid = $results->fields['id'];                
                if ($type == 'r') {
                    ($results->fields['access']  == 1)? ($db->Execute("DELETE FROM $o_pritable WHERE id = $tmpid")):($db->Execute("UPDATE $o_pritable SET access = 2 WHERE id = $tmpid"));
                } else if($type == 'w') {
                    ($results->fields['access']  == 2)? ($db->Execute("DELETE FROM $o_pritable WHERE id = $tmpid")):($db->Execute("UPDATE $o_pritable SET access = 1 WHERE id = $tmpid"));
                }
                $results->MoveNext();
            }
    } else {
        //Update children and self access
        $results = $db->Execute("SELECT * FROM $o_pritable WHERE $o_id = $s_id AND repositoryid = $s_repositoryid AND path LIKE '$s_path%' ");
        if (!$results) 
            print $db->ErrorMsg();
        else
            while (!$results->EOF) {
                $tmpid = $results->fields['id'];                
                if ($type == 'r') {
                    ($results->fields['access']  == 1)? ($db->Execute("DELETE FROM $o_pritable WHERE id = $tmpid")):($db->Execute("UPDATE $o_pritable SET access = 2 WHERE id = $tmpid"));
                } else if($type == 'w') {
                    ($results->fields['access']  == 2)? ($db->Execute("DELETE FROM $o_pritable WHERE id = $tmpid")):($db->Execute("UPDATE $o_pritable SET access = 1 WHERE id = $tmpid"));
                }
                $results->MoveNext();
            }

        //Update parents access
        if (isset($dispath))
            foreach($dispath as $d_path) {
                if (strpos($path, $d_path) === 0) {
                    $s_d_path = makeSqlString(pathFilter($d_path));
                    $results = $db->Execute("SELECT * FROM $o_pritable WHERE $o_id = $s_id AND repositoryid = $s_repositoryid AND path = $s_d_path ");
                    if (!$results) 
                        print $db->ErrorMsg();
                    else {
                        $tmpid = $results->fields['id'];                
                        if ($type == 'r') {
                            ($results->fields['access']  == 1)? ($db->Execute("DELETE FROM $o_pritable WHERE id = $tmpid")):($db->Execute("UPDATE $o_pritable SET access = 2 WHERE id = $tmpid"));
                        } else if($type == 'w') {
                            ($results->fields['access']  == 2)? ($db->Execute("DELETE FROM $o_pritable WHERE id = $tmpid")):($db->Execute("UPDATE $o_pritable SET access = 1 WHERE id = $tmpid"));
                        }   
                    }
                }
            }
    }
}

function getUserGroup($name, $option, $option2, $config) {
    $db         = $config->db;
    $tmpug      = array('linked'=>array(),'unlinked'=>array());

    $o_table    = $option . 's';
    $o_id       = $option . 'id';
    $d_table    = $option2 . 's';
    $d_id       = $option2 . 'id';

    $s_name     = makeSqlString($name);
    $s_all      = makeSqlString('*');

    $results    = $db->Execute("SELECT dt.name FROM $o_table ot, $d_table dt, usersgroups ug  WHERE ot.name <> $s_all AND ot.name = $s_name AND ot.id = ug.$o_id AND ug.$d_id = dt.id ");
    if (!$results) 
        print $db->ErrorMsg();
    else 
        while(!$results->EOF) {
            $tmpug['linked'][] = $results->fields['name'];
            $results->MoveNext();
        }
    $results    = $db->Execute("SELECT name FROM $d_table  WHERE name <> $s_all");
    if (!$results) 
        print $db->ErrorMsg();
    else 
        foreach($results->GetArray() as $rs) {
            $tmpug['unlinked'][] = $rs['name'];
        }
    $tmpug['unlinked'] = array_diff($tmpug['unlinked'], $tmpug['linked']);
    return $tmpug;
}

function addOrRemoveUG($name, $name2, $type, $option, $config) {
    $db         = $config->db;
    $tmpoption  = explode('to', $option);

    $table      = $tmpoption[0] . 's';
    $id         = $tmpoption[0] . 'id';
    $table2     = $tmpoption[1] . 's';
    $id2        = $tmpoption[1] . 'id';
    $tmpid      = "";
    $tmpid2     = "";

    $s_name     = makeSqlString($name);
    $s_name2    = makeSqlString($name2);

    $results    = $db->Execute("SELECT id FROM $table WHERE name = $s_name ");
    if (!$results)
        print $db->ErrorMsg();
    else
        $tmpid  = $results->fields['id'];

    $results    = $db->Execute("SELECT id FROM $table2 WHERE name = $s_name2 ");
    if (!$results)
        print $db->ErrorMsg();
    else
        $tmpid2 = $results->fields['id'];

    if ($type=='unlinked') {
        $results= $db->Execute("DELETE FROM usersgroups WHERE $id = $tmpid AND $id2 = $tmpid2");
    } else if ($type == 'linked') {
        $results= $db->Execute("INSERT INTO usersgroups SET $id = $tmpid , $id2 = $tmpid2");
    }
}

function getValidDate($path, $name, $repositoryName, $option, $config) {
    $db         = $config->db;

    $o_table    = $option . 's';
    $o_pritable = $option . 'privileges';
    $o_id       = $option . 'id';

    $s_name     = makeSqlString($name);
    $results    = $db->Execute("SELECT id FROM $o_table WHERE name = $s_name");
    $s_id       = $results->fields['id'];

    $s_repositoryName   = makeSqlString($repositoryName);
    $results            = $db->Execute("SELECT id FROM repositories WHERE name = $s_repositoryName");
    $s_repositoryid     = $results->fields['id'];

    $s_path     = makeSqlString(pathFilter($path));

    $results    = $db->Execute("SELECT vdate FROM $o_pritable WHERE $o_id = $s_id AND repositoryid = $s_repositoryid AND path = $s_path ");

    if (!$results)
        print $db->ErrorMsg();
    else
        return $results->fields['vdate'];
}

function updateVDate($name, $repositoryName, $path, $vdate, $option, $config) {

    $db         = $config->db;
    $o_table    = $option . 's';
    $o_pritable = $option . 'privileges';
    $o_id       = $option . 'id';

    $s_name     = makeSqlString($name);
    $results    = $db->Execute("SELECT id FROM $o_table WHERE name = $s_name");
    $s_id       = $results->fields['id'];

    $s_repositoryName   = makeSqlString($repositoryName);
    $results            = $db->Execute("SELECT id FROM repositories WHERE name = $s_repositoryName");
    $s_repositoryid     = $results->fields['id'];

    $s_path     = makeSqlString(pathFilter($path));
    $s_vdate    = makeSqlString($vdate);

    $db->Execute("UPDATE $o_pritable SET vdate = $s_vdate 
            WHERE $o_id = $s_id AND repositoryid = $s_repositoryid AND path = $s_path");
}

function getIsAdmin($name, $config) {

    $db         = $config->db;
    $s_name     = makeSqlString($name);

    $results    = $db->Execute("SELECT admin FROM users WHERE name = $s_name ");
    if (!$results)
        print $db->ErrorMsg();
    else if ($results->fields['admin'] == 255) return true;
    else return false;
}

function getIsExist($name, $option, $config) {
    $db         = $config->db;
    $o_table    = $option . 's';
    $s_name     = makeSqlString($name);

    $results    = $db->Execute("SELECT * FROM $o_table WHERE name = $s_name ");
    if (!$results->EOF)
        return true;
    else return false;
}

function userAddOrUpdate($name, $isAdmin, $config, $password=null) {
    $db         = $config->db;
    $s_name     = makeSqlString($name);
    $a_name     = escapeshellarg($name);
    $htpassword_cmd  = $config->htpassword;
    $svn_passwd_file = $config->passwdFile;

    if($password){
        $a_password = escapeshellarg($password);
        $s_password = makeSqlString(md5($password));
    }
    
    $results    = $db->Execute("SELECT * FROM users WHERE name = $s_name ");
    if (!$results->EOF){
        $db->Execute("UPDATE users SET admin = $isAdmin");
    } else {
        $db->Execute("INSERT INTO users (id, name, password, admin) VALUES (null, 
            $s_name, $s_password, $isAdmin)");

        if(!file_exists($svn_passwd_file)){
            exec("$htpassword_cmd -cmb $svn_passwd_file $a_name $a_password");
        } else {
            exec("$htpassword_cmd -bm $svn_passwd_file $a_name $a_password");
        }
    }
}

function groupAdd($name, $config) {
    $db         = $config->db;
    $s_name     = makeSqlString($name);
    $s_username = makeSqlString($config->auth->user);
    $results    = $db->Execute("SELECT id FROM users WHERE name = $s_username");
    $s_id       = $results->fields['id'];

    $db->Execute("INSERT INTO groups (id, name, adminid) VALUES (null, $s_name, $s_id)");
}

function repoAdd($name, $desc, $config) {
    $db         = $config->db;

    $s_name     = makeSqlString($name);
    $s_ownername= makeSqlString($config->auth->user);
    $results    = $db->Execute("SELECT id FROM users WHERE name = $s_ownername");
    $s_id       = $results->fields['id'];

    $s_desc     = makeSqlString($desc);

    $svnadmin_cmd   = $config->svnadmin;
    $svn_config_dir = $config->svnConfig;
    $a_dir          = $config->svnRepos.DIRECTORY_SEPARATOR.escapeshellarg($name);

    $db->Execute("INSERT INTO repositories (id, name, ownerid) VALUES (null, $s_name, $s_id)");
    $results    = $db->Execute("SELECT * FROM repositories WHERE name = $s_name ");
    $tmp_id     = $results->fields['id'];
    $db->Execute("INSERT INTO repo_descriptions (id, repo_id, description) VALUES (null, $tmp_id, $s_desc)");

    $ret = exec("$svnadmin_cmd --config-dir $svn_config_dir create $a_dir");                         
    if($ret!="") {
        print("svnadmin failed: $ret");
    }
}

function userOrGroupDelete($name, $option, $config) {

    $db         = $config->db;
    $o_table    = $option . 's';
    $o_pritable = $option . 'privileges';
    $o_id       = $option . 'id';
    $htpassword_cmd  = $config->htpassword;
    $svn_passwd_file = $config->passwdFile;

    $s_name     = makeSqlString($name);
    $a_name     = escapeshellarg($name);

    $results    = $db->Execute("SELECT id FROM $o_table WHERE name = $s_name");
    $s_id       = $results->fields['id'];
    
    $db->Execute("DELETE FROM $o_pritable WHERE $o_id = $s_id ");
    $db->Execute("DELETE FROM usersgroups WHERE $o_id = $s_id ");
    $db->Execute("DELETE FROM $o_table WHERE name = $s_name ");
    exec("$htpassword_cmd -D $svn_passwd_file $a_name");
}

function repoDelete($name, $config) {

    $db         = $config->db;

    $s_name     = makeSqlString($name);
    $results    = $db->Execute("SELECT id FROM repositories WHERE name = $s_name");
    $s_id       = $results->fields['id'];

    $arg_repo_path  = $config->svnRepos.DIRECTORY_SEPARATOR.escapeshellarg($name);
    
    $db->Execute("DELETE FROM groupprivileges WHERE repositoryid = $s_id ");
    $db->Execute("DELETE FROM userprivileges WHERE repositoryid = $s_id ");
    $db->Execute("DELETE FROM repo_descriptions WHERE repo_id = $s_id ");
    $db->Execute("DELETE FROM repositories WHERE id = $s_id ");
    
    $ret = exec("rm -rf $arg_repo_path 2>&1");                                                              
    if($ret!="") {
        print("Removing failed: $ret");
    }
}

function checkUserAble($path, $user, $rep, $config) {
    $tmpaccess  = array('','','','','','');

    $db         = $config->db;
    $s_name     = makeSqlString($user);
    $results    = $db->Execute("SELECT id FROM users WHERE name = $s_name");
    $s_id       = $results->fields['id'];

    $s_repositoryName   = makeSqlString($rep);
    $results            = $db->Execute("SELECT id FROM repositories WHERE name = $s_repositoryName");
    $s_repositoryid     = $results->fields['id'];

    $s_path = makeSqlString(pathFilter($path));

    $results = $db->Execute("SELECT * FROM userprivileges WHERE userid = $s_id AND repositoryid = $s_repositoryid AND path = $s_path");
    if (!$results)
        print $db->ErrorMsg();
    else if(!$results->EOF) {
        $access = $results->fields['access'];
        switch($access){
            case 1:
                $tmpaccess[0]   = true;
                break;
            case 2:
                $tmpaccess[1]   = true;
                break;
            case 3:
                $tmpaccess[0]   = true;
                $tmpaccess[1]   = true;
                break;
        }
    }
    
    $results = $db->Execute("SELECT * FROM usersgroups WHERE userid = $s_id");
    if (!$results)
        print $db->ErrorMsg();
    else {
        $tmpgroupid = array();
        while (!$results->EOF) {
            $tmpgroupid[] = $results->fields['groupid'];
            $results->MoveNext();
        }
        foreach($tmpgroupid as $tmp_id) {
            $results2 = $db->Execute("SELECT * FROM groupprivileges WHERE groupid = $tmp_id AND repositoryid = $s_repositoryid AND path = $s_path");
            if (!$results2)
                print $db->ErrorMsg();
            else if(!$results2->EOF) {
                $access = $results2->fields['access'];
                switch($access){
                    case 1:
                        $tmpaccess[2]   = true;
                        break;
                    case 2:
                        $tmpaccess[3]   = true;
                        break;
                    case 3:
                        $tmpaccess[2]   = true;
                        $tmpaccess[3]   = true;
                        break;
                }
            }
        }
    }

    $s_name     = makeSqlString('*');
    $results    = $db->Execute("SELECT id FROM users WHERE name = $s_name");
    if (!$results)
        print $db->ErrorMsg();
    else if(!$results->EOF){
        $s_id       = $results->fields['id'];
        $results2   = $db->Execute("SELECT * FROM userprivileges WHERE userid = $s_id AND repositoryid = $s_repositoryid AND path = $s_path");
        if (!$results2)
            print $db->ErrorMsg();
        else if(!$results2->EOF) {
            $access = $results2->fields['access'];
            switch($access){
                case 1:
                    $tmpaccess[5]   = true;
                    break;
                case 2:
                    $tmpaccess[6]   = true;
                    break;
                case 3:
                    $tmpaccess[5]   = true;
                    $tmpaccess[6]   = true;
                    break;
            }
        }
    }
    return $tmpaccess;
}

function checkGroupAble($path, $group, $rep, $config) {
    $tmpaccess  = array('','');

    $db         = $config->db;
    $s_name     = makeSqlString($group);
    $results    = $db->Execute("SELECT id FROM groups WHERE name = $s_name");
    $s_id       = $results->fields['id'];

    $s_repositoryName   = makeSqlString($rep);
    $results            = $db->Execute("SELECT id FROM repositories WHERE name = $s_repositoryName");
    $s_repositoryid     = $results->fields['id'];

    $s_path     = makeSqlString(pathFilter($path));
    
    $results    = $db->Execute("SELECT * FROM groupprivileges WHERE groupid = $s_id AND repositoryid = $s_repositoryid AND path = $s_path");
    if (!$results)
        print $db->ErrorMsg();
    else if(!$results->EOF) {
        $access = $results->fields['access'];
        switch($access){
            case 1:
                $tmpaccess[0]   = true;
                break;
            case 2:
                $tmpaccess[1]   = true;
                break;
            case 3:
                $tmpaccess[0]   = true;
                $tmpaccess[1]   = true;
                break;
        }
    }
    return $tmpaccess;
}

